package com.zztl.infiniteBand.ui.view

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
import android.view.animation.LinearInterpolator
import com.zztl.infiniteBand.R


/**
 *  @desc
 *  @auth ${user}
 *  @time 2018/10/24  16:57
 */
class WaveViewBySinCos(var mContext: Context, var attrs: AttributeSet) : View(mContext, attrs) {
    /**
     * 振幅
     */
    private var A: Int = 0
    /**
     * 偏距
     */
    private var K: Int

    /**
     * 波形的颜色
     */
    private var waveColor = -0x550081c9

    /**
     * 初相
     */
    private var φ: Float = 0.toFloat()

    /**
     * 波形移动的速度
     */
    private var waveSpeed = 3f

    /**
     * 角速度
     */
    private var ω: Double = 0.toDouble()

    /**
     * 开始位置相差多少个周期
     */
    private var startPeriod: Double = 0.toDouble()

    /**
     * 是否直接开启波形
     */
    private var waveStart: Boolean = false

    private var path: Path? = null
    private var paint: Paint? = null

    private val SIN = 0
    private val COS = 1

    private var waveType: Int = 0

    private val TOP = 0
    private val BOTTOM = 1

    private var waveFillType: Int = 0

    private var valueAnimator: ValueAnimator? = null


    init {
        getAttr(attrs)
        K = A
        initPaint()
        initAnimation()
    }

    private fun getAttr(attrs: AttributeSet) {
        val typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.RadarWaveView)

        waveType = typedArray.getInt(R.styleable.RadarWaveView_waveType, SIN)
        waveFillType = typedArray.getInt(R.styleable.RadarWaveView_waveFillType, TOP)
        A = typedArray.getDimensionPixelOffset(R.styleable.RadarWaveView_waveAmplitude, dp2px(10))
        waveColor = typedArray.getColor(R.styleable.RadarWaveView_waveColor, Color.parseColor("#3485FD"))
        waveSpeed = typedArray.getFloat(R.styleable.RadarWaveView_waveSpeed, waveSpeed)
        startPeriod = typedArray.getFloat(R.styleable.RadarWaveView_waveStartPeriod, 0f).toDouble()
        waveStart = typedArray.getBoolean(R.styleable.RadarWaveView_waveStart, false)

        typedArray.recycle()
    }

    private fun initPaint() {
        path = Path()
        paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
            isAntiAlias = true
            style = Paint.Style.FILL_AND_STROKE
            color = waveColor
        }

    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        ω = 2 * Math.PI / width
    }

    override fun onDraw(canvas: Canvas) {

        when (waveType) {
            SIN -> drawSin(canvas)
            COS -> drawCos(canvas)
        }

    }


    /**
     * 根据cos函数绘制波形
     *
     * @param canvas
     */
    private fun drawCos(canvas: Canvas) {

        when (waveFillType) {
            TOP -> fillTop(canvas)
            BOTTOM -> fillBottom(canvas)
        }
    }

    /**
     * 根据sin函数绘制波形
     *
     * @param canvas
     */
    private fun drawSin(canvas: Canvas) {

        when (waveFillType) {
            TOP -> fillTop(canvas)
            BOTTOM -> fillBottom(canvas)
        }

    }

    /**
     * 填充波浪上面部分
     */
    private fun fillTop(canvas: Canvas) {

        φ -= waveSpeed / 100
        var y: Float
        path?.apply {
            reset()
            moveTo(0f, height.toFloat())

            var x = 0f
            while (x <= width) {
                y = (A * Math.sin(ω * x + φ.toDouble() + Math.PI * startPeriod) + K).toFloat()
                path!!.lineTo(x, height - y)
                x += 20f
            }

            lineTo(width.toFloat(), 0f)
            lineTo(0f, 0f)
            close()
            canvas.drawPath(path, paint)
        }


    }

    /**
     * 填充波浪下面部分
     */
    private fun fillBottom(canvas: Canvas) {

        φ -= waveSpeed / 100
        var y: Float

        path?.apply {
            reset()
            moveTo(0f, 0f)

            var x = 0f
            while (x <= width) {
                y = (A * Math.sin(ω * x + φ.toDouble() + Math.PI * startPeriod) + K).toFloat()
                path!!.lineTo(x, y)
                x += 20f
            }

            //填充矩形
            lineTo(width.toFloat(), height.toFloat())
            lineTo(0f, height.toFloat())
            close()

            canvas.drawPath(path, paint)

        }


    }

    private fun initAnimation() {
        valueAnimator = ValueAnimator.ofInt(0, width).apply {
            duration = 100
            repeatCount = ValueAnimator.INFINITE
            interpolator = LinearInterpolator()
            addUpdateListener {
                /**
                 * 刷新页面调取onDraw方法，通过变更φ 达到移动效果
                 */
                invalidate()
            }
            if (waveStart) {
                start()
            }
        }


    }

    fun startAnimation() {
        valueAnimator?.start()
    }

    fun stopAnimation() {
        valueAnimator?.cancel()
    }

    fun pauseAnimation() {
        valueAnimator?.pause()
    }

    fun resumeAnimation() {
        valueAnimator?.resume()
    }

    /**
     * dp 2 px
     *
     * @param dpVal
     */
    protected fun dp2px(dpVal: Int): Int {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dpVal.toFloat(), resources.displayMetrics).toInt()
    }
}